package com.cardcaptorsakura.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;

/**
 * 文件存储配置类
 */
@Data
@Configuration
@ConfigurationProperties(prefix = "file.storage")
public class FileStorageConfig {

    /**
     * 基础存储目录
     */
    private String baseDir = "./storage";

    /**
     * 上传目录
     */
    private String uploadDir = "uploads";

    /**
     * 下载目录
     */
    private String downloadDir = "downloads";

    /**
     * 临时文件目录
     */
    private String tempDir = "temp";

    /**
     * 图像存储目录
     */
    private String imageDir = "images";

    /**
     * 音频存储目录
     */
    private String audioDir = "audio";

    /**
     * 视频存储目录
     */
    private String videoDir = "video";

    /**
     * 文档存储目录
     */
    private String documentDir = "documents";

    /**
     * 缓存目录
     */
    private String cacheDir = "cache";

    /**
     * 备份目录
     */
    private String backupDir = "backup";

    /**
     * 最大文件大小（字节）
     */
    private Long maxFileSize = 100L * 1024 * 1024; // 100MB

    /**
     * 最大图像文件大小（字节）
     */
    private Long maxImageSize = 20L * 1024 * 1024; // 20MB

    /**
     * 最大音频文件大小（字节）
     */
    private Long maxAudioSize = 50L * 1024 * 1024; // 50MB

    /**
     * 最大视频文件大小（字节）
     */
    private Long maxVideoSize = 200L * 1024 * 1024; // 200MB

    /**
     * 允许的图像文件类型
     */
    private List<String> allowedImageTypes = Arrays.asList(
            "jpg", "jpeg", "png", "gif", "bmp", "webp", "svg"
    );

    /**
     * 允许的音频文件类型
     */
    private List<String> allowedAudioTypes = Arrays.asList(
            "mp3", "wav", "flac", "aac", "ogg", "m4a", "wma"
    );

    /**
     * 允许的视频文件类型
     */
    private List<String> allowedVideoTypes = Arrays.asList(
            "mp4", "avi", "mov", "wmv", "flv", "webm", "mkv"
    );

    /**
     * 允许的文档文件类型
     */
    private List<String> allowedDocumentTypes = Arrays.asList(
            "txt", "pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "rtf"
    );

    /**
     * 文件名生成策略
     */
    private FileNamingStrategy namingStrategy = FileNamingStrategy.UUID;

    /**
     * 是否保留原始文件名
     */
    private Boolean keepOriginalName = false;

    /**
     * 文件名最大长度
     */
    private Integer maxFileNameLength = 255;

    /**
     * 是否启用文件压缩
     */
    private Boolean enableCompression = true;

    /**
     * 图像压缩质量（0-100）
     */
    private Integer imageCompressionQuality = 85;

    /**
     * 是否生成缩略图
     */
    private Boolean generateThumbnails = true;

    /**
     * 缩略图尺寸
     */
    private ThumbnailConfig thumbnail = new ThumbnailConfig();

    /**
     * 是否启用文件去重
     */
    private Boolean enableDeduplication = true;

    /**
     * 文件哈希算法
     */
    private String hashAlgorithm = "SHA-256";

    /**
     * 是否启用文件加密
     */
    private Boolean enableEncryption = false;

    /**
     * 加密算法
     */
    private String encryptionAlgorithm = "AES";

    /**
     * 是否启用文件版本控制
     */
    private Boolean enableVersioning = false;

    /**
     * 最大版本数
     */
    private Integer maxVersions = 10;

    /**
     * 临时文件清理间隔（小时）
     */
    private Integer tempFileCleanupInterval = 24;

    /**
     * 临时文件保留时间（小时）
     */
    private Integer tempFileRetentionHours = 48;

    /**
     * 是否启用文件访问日志
     */
    private Boolean enableAccessLog = true;

    /**
     * 访问日志保留天数
     */
    private Integer accessLogRetentionDays = 30;

    /**
     * 是否启用文件病毒扫描
     */
    private Boolean enableVirusScan = false;

    /**
     * 病毒扫描引擎
     */
    private String virusScanEngine = "clamav";

    /**
     * CDN配置
     */
    private CdnConfig cdn = new CdnConfig();

    /**
     * 云存储配置
     */
    private CloudStorageConfig cloudStorage = new CloudStorageConfig();

    /**
     * 文件命名策略枚举
     */
    public enum FileNamingStrategy {
        UUID,           // 使用UUID
        TIMESTAMP,      // 使用时间戳
        HASH,           // 使用文件哈希
        ORIGINAL,       // 保持原始名称
        CUSTOM          // 自定义策略
    }

    /**
     * 缩略图配置
     */
    @Data
    public static class ThumbnailConfig {
        /**
         * 是否启用
         */
        private Boolean enabled = true;

        /**
         * 小缩略图尺寸
         */
        private Integer smallSize = 150;

        /**
         * 中等缩略图尺寸
         */
        private Integer mediumSize = 300;

        /**
         * 大缩略图尺寸
         */
        private Integer largeSize = 600;

        /**
         * 缩略图质量（0-100）
         */
        private Integer quality = 80;

        /**
         * 缩略图格式
         */
        private String format = "jpg";

        /**
         * 是否保持宽高比
         */
        private Boolean keepAspectRatio = true;

        /**
         * 背景颜色（当不保持宽高比时）
         */
        private String backgroundColor = "#FFFFFF";
    }

    /**
     * CDN配置
     */
    @Data
    public static class CdnConfig {
        /**
         * 是否启用CDN
         */
        private Boolean enabled = false;

        /**
         * CDN域名
         */
        private String domain;

        /**
         * CDN路径前缀
         */
        private String pathPrefix = "/files";

        /**
         * 是否使用HTTPS
         */
        private Boolean useHttps = true;

        /**
         * 缓存控制头
         */
        private String cacheControl = "public, max-age=31536000";

        /**
         * CDN提供商
         */
        private String provider = "aliyun";

        /**
         * 访问密钥ID
         */
        private String accessKeyId;

        /**
         * 访问密钥
         */
        private String accessKeySecret;

        /**
         * 存储桶名称
         */
        private String bucketName;

        /**
         * 地域
         */
        private String region;
    }

    /**
     * 云存储配置
     */
    @Data
    public static class CloudStorageConfig {
        /**
         * 是否启用云存储
         */
        private Boolean enabled = false;

        /**
         * 云存储提供商（aliyun, tencent, aws, etc.）
         */
        private String provider = "aliyun";

        /**
         * 访问密钥ID
         */
        private String accessKeyId;

        /**
         * 访问密钥
         */
        private String accessKeySecret;

        /**
         * 存储桶名称
         */
        private String bucketName;

        /**
         * 地域
         */
        private String region;

        /**
         * 端点URL
         */
        private String endpoint;

        /**
         * 是否使用HTTPS
         */
        private Boolean useHttps = true;

        /**
         * 连接超时（毫秒）
         */
        private Integer connectionTimeout = 10000;

        /**
         * 读取超时（毫秒）
         */
        private Integer readTimeout = 30000;

        /**
         * 最大连接数
         */
        private Integer maxConnections = 100;

        /**
         * 是否启用本地缓存
         */
        private Boolean enableLocalCache = true;

        /**
         * 本地缓存大小（MB）
         */
        private Integer localCacheSize = 1000;

        /**
         * 本地缓存过期时间（小时）
         */
        private Integer localCacheExpiration = 24;
    }

    /**
     * 获取完整路径
     */
    public Path getFullPath(String relativePath) {
        return Paths.get(baseDir, relativePath);
    }

    /**
     * 获取上传目录完整路径
     */
    public Path getUploadPath() {
        return getFullPath(uploadDir);
    }

    /**
     * 获取下载目录完整路径
     */
    public Path getDownloadPath() {
        return getFullPath(downloadDir);
    }

    /**
     * 获取临时目录完整路径
     */
    public Path getTempPath() {
        return getFullPath(tempDir);
    }

    /**
     * 获取图像目录完整路径
     */
    public Path getImagePath() {
        return getFullPath(imageDir);
    }

    /**
     * 获取音频目录完整路径
     */
    public Path getAudioPath() {
        return getFullPath(audioDir);
    }

    /**
     * 获取视频目录完整路径
     */
    public Path getVideoPath() {
        return getFullPath(videoDir);
    }

    /**
     * 获取文档目录完整路径
     */
    public Path getDocumentPath() {
        return getFullPath(documentDir);
    }

    /**
     * 获取缓存目录完整路径
     */
    public Path getCachePath() {
        return getFullPath(cacheDir);
    }

    /**
     * 获取备份目录完整路径
     */
    public Path getBackupPath() {
        return getFullPath(backupDir);
    }

    /**
     * 检查文件类型是否允许
     */
    public boolean isFileTypeAllowed(String fileExtension, String category) {
        if (fileExtension == null) return false;
        
        String ext = fileExtension.toLowerCase();
        if (ext.startsWith(".")) {
            ext = ext.substring(1);
        }
        
        switch (category.toLowerCase()) {
            case "image":
                return allowedImageTypes.contains(ext);
            case "audio":
                return allowedAudioTypes.contains(ext);
            case "video":
                return allowedVideoTypes.contains(ext);
            case "document":
                return allowedDocumentTypes.contains(ext);
            default:
                // 检查所有类型
                return allowedImageTypes.contains(ext) ||
                       allowedAudioTypes.contains(ext) ||
                       allowedVideoTypes.contains(ext) ||
                       allowedDocumentTypes.contains(ext);
        }
    }

    /**
     * 检查文件大小是否允许
     */
    public boolean isFileSizeAllowed(long fileSize, String category) {
        switch (category.toLowerCase()) {
            case "image":
                return fileSize <= maxImageSize;
            case "audio":
                return fileSize <= maxAudioSize;
            case "video":
                return fileSize <= maxVideoSize;
            default:
                return fileSize <= maxFileSize;
        }
    }

    /**
     * 获取文件类别
     */
    public String getFileCategory(String fileExtension) {
        if (fileExtension == null) return "unknown";
        
        String ext = fileExtension.toLowerCase();
        if (ext.startsWith(".")) {
            ext = ext.substring(1);
        }
        
        if (allowedImageTypes.contains(ext)) return "image";
        if (allowedAudioTypes.contains(ext)) return "audio";
        if (allowedVideoTypes.contains(ext)) return "video";
        if (allowedDocumentTypes.contains(ext)) return "document";
        
        return "other";
    }

    /**
     * 获取存储路径（根据文件类别）
     */
    public Path getStoragePathByCategory(String category) {
        switch (category.toLowerCase()) {
            case "image":
                return getImagePath();
            case "audio":
                return getAudioPath();
            case "video":
                return getVideoPath();
            case "document":
                return getDocumentPath();
            default:
                return getUploadPath();
        }
    }

    /**
     * 生成文件名
     */
    public String generateFileName(String originalName, String extension) {
        switch (namingStrategy) {
            case UUID:
                return java.util.UUID.randomUUID().toString() + "." + extension;
            case TIMESTAMP:
                return System.currentTimeMillis() + "_" + 
                       (originalName != null ? originalName.replaceAll("[^a-zA-Z0-9.-]", "_") : "file") + 
                       "." + extension;
            case HASH:
                // 这里需要文件内容来计算哈希，暂时使用UUID
                return java.util.UUID.randomUUID().toString() + "." + extension;
            case ORIGINAL:
                return originalName != null ? originalName : "file." + extension;
            case CUSTOM:
                // 自定义逻辑，这里使用时间戳+随机数
                return System.currentTimeMillis() + "_" + 
                       (int)(Math.random() * 10000) + "." + extension;
            default:
                return java.util.UUID.randomUUID().toString() + "." + extension;
        }
    }

    /**
     * 验证配置
     */
    public boolean validateConfig() {
        // 检查基础目录是否设置
        if (baseDir == null || baseDir.trim().isEmpty()) {
            return false;
        }
        
        // 检查文件大小限制是否合理
        if (maxFileSize <= 0 || maxImageSize <= 0 || maxAudioSize <= 0 || maxVideoSize <= 0) {
            return false;
        }
        
        // 检查允许的文件类型列表是否为空
        if (allowedImageTypes.isEmpty() && allowedAudioTypes.isEmpty() && 
            allowedVideoTypes.isEmpty() && allowedDocumentTypes.isEmpty()) {
            return false;
        }
        
        return true;
    }

    /**
     * 获取配置摘要
     */
    public String getConfigSummary() {
        return String.format("存储目录: %s, 最大文件大小: %dMB, 支持文件类型: %d种",
                baseDir,
                maxFileSize / (1024 * 1024),
                allowedImageTypes.size() + allowedAudioTypes.size() + 
                allowedVideoTypes.size() + allowedDocumentTypes.size());
    }
}